/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.worlds;

import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;


public class Settings {
    private static HashMap<String, SettingDef> settingDefs = new HashMap<String, SettingDef>(16);
    private static HashMap<String, Object> settings = new HashMap<String, Object>(16);
    private static void addSetting(String name, Object defaultValue, SettingChangeHandler handler)
    {
        SettingDef sd = new SettingDef();
        sd.name = name;
        sd.defaultValue = defaultValue;
        sd.valueClass = defaultValue.getClass();
        sd.handler = handler;
        settingDefs.put(name, sd);
        settings.put(name, defaultValue);
    }
    public static HashMap<String, Object> getAllSettings()
    {
        return settings;
    }
    public static SettingDef getSettingDef(String name)
    {
        return settingDefs.get(name);
    }
    public static void set(String name, Object value, boolean fireEvent)
    {
        try {
            Object oldValue = settings.get(name);
            settings.put(name, value);
            if (fireEvent) {
                SettingChangeHandler handler = settingDefs.get(name).handler;
                if(handler != null)
                    handler.handle(oldValue, value);
            }
        } catch (WorldsException ex) {
            throw new RuntimeException("Error changing setting: "+ex);
        }
    }
    public static void persist()
    {
        Preferences prefs = Preferences.userNodeForPackage(Main.class);
        for(String k : settings.keySet())
        {
            Object v = settings.get(k);
            if(v instanceof String)
                prefs.put(k, v.toString());
            else if(v instanceof Integer)
                prefs.putInt(k, (Integer) v);
            else if(v instanceof Float)
                prefs.putFloat(k, (Float) v);
            else if(v instanceof Boolean)
                prefs.putBoolean(k, (Boolean) v);
        }
    }
    public static void restore()
    {
        try {
            Preferences prefs = Preferences.userNodeForPackage(Main.class);
            for (String k : prefs.keys()) {
                if(settings.containsKey(k))
                {
                    SettingDef def = settingDefs.get(k);
                    Class c = def.valueClass;
                    Object d = def.defaultValue;
                    Object value = null;
                    if(c == String.class)
                        value = prefs.get(k, (String)d);
                    else if(c == Integer.class)
                    {
                        value = prefs.getInt(k, (Integer)d);
                        if((Integer) value == 0)
                        {
                            value = d;
                        }
                    }
                    else if(c == Float.class)
                        value = prefs.getFloat(k, (Float) d);
                    else if(c == Boolean.class)
                        value = prefs.getBoolean(k, (Boolean)d);
                    if(value != null)
                        set(k, value, false);
                }
            }
        } catch (BackingStoreException ex) {
            Main.log("Error loading settings!", ex);
        }
    }
    public static void revert()
    {
        for(SettingDef sd : settingDefs.values())
        {
            set(sd.name, sd.defaultValue, true);
        }
        persist();
    }
    public static int getInt(String k)
    {
        return (Integer) settings.get(k);
    }
    public static float getFloat(String k)
    {
        return (Float) settings.get(k);
    }
    public static String getString(String k)
    {
        return (String) settings.get(k);
    }
    public static boolean getBoolean(String k)
    {
        return (Boolean) settings.get(k);
    }
    static
    {
        addSetting("Antialiasing", false, new SettingChangeHandler()
        {
            public void handle(Object oldValue, Object value) throws WorldsException {
                if(!Main.noView)
                    Main.getView().setAntialiasing((Boolean)value);
            }
        });
        addSetting("FPS", 120, new SettingChangeHandler()
        {
            public void handle(Object oldValue, Object value) throws WorldsException {

            }
        });
        addSetting("ControlPhysicsFPS", true, new SettingChangeHandler()
        {
            @Override
            public void handle(Object oldValue, Object value) throws WorldsException {

            }
        });
        addSetting("UsePerfectCollisions", false, new SettingChangeHandler()
        {
            public void handle(Object oldValue, Object value) throws WorldsException {

            }
        });
        addSetting("PhysicsAccuracy", 16, new SettingChangeHandler()
        {
            public void handle(Object oldValue, Object value) throws WorldsException {

            }
        });
    }
}
